using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using OpenComposite.Base.Designer;
using OpenComposite.EII.Repository;
using OpenComposite.Base.Collections;
using System.ComponentModel;
using OpenComposite.EII.Services;

namespace OpenComposite.EII.Designer.SCA
{
	public class CompositeSymbol : Symbol, IRepositoryItemSymbol
	{
		#region Initialization
		public CompositeSymbol()
		{
			init();
		}
		private void init()
		{
			this.BeginUpdate();

			this.Border = BorderType.RoundedRectangle;
			this.BorderColor = Color.Black;
			this.BorderStyle = System.Drawing.Drawing2D.DashStyle.Solid;
			this.BorderWidth = 2;

			this.BackColor = Color.FromArgb(64, 121, 137, 251);
			this.BackColor2 = Color.FromArgb(64, 121, 137, 251);
			this.BackBrushMode = BackgroundBrushMode.LinearGradient;
			this.BackLinearGradientMode = LinearGradientMode.ForwardDiagonal;

			//this.Name = "serviceModuleSymbol" + GetCount(typeof(ServiceModuleSymbol));
			this.Text = "Service";

			this.Size = new Size(600, 300);
			this.MinimumSize = new Size(70, 50);

			this.NameTextBox.AutoSize = false;
			this.NameTextBox.Width = this.NameTextBox.Width - 20;

			//this.CollapsedSize = new Size(130, 80);
			//this.CollapsedBorderColor = Color.Black;
			//this.CollapsedBackColor = Color.FromArgb(255, 153, 1);
			//this.CollapsedBackColor2 = Color.White;
			//this.ExpandedSize = new Size(600, 300);
			//this.ExpandedBorderColor = Color.Black;
			//this.ExpandedBackColor = Color.FromArgb(64, 121, 137, 251);
			//this.ExpandedBackColor2 = Color.FromArgb(64, 121, 137, 251);

			//
			// this.ContextMenuStrip
			//
			this.ContextMenuStrip = new ContextMenuStrip();
			this.ContextMenuStrip.Items.Add("Open Service", null, new EventHandler(context_Open)).Name = "opencomposite";
			this.ContextMenuStrip.Items.Add(new ToolStripSeparator());
			this.ContextMenuStrip.Items.Add("Generate Web Service...", OpenComposite.Repository.Properties.Resources.PublishToWeb, new EventHandler(context_Deploy)).Name = "deploycomposite";
			this.ContextMenuStrip.Items["deploycomposite"].ImageTransparentColor = Color.Magenta;
			this.ContextMenuStrip.Items.Add(new ToolStripSeparator());
			this.ContextMenuStrip.Items.Add("Remove Service", null, new EventHandler(context_Remove));
			this.ContextMenuStrip.Items.Add("Delete Service", OpenComposite.Repository.Properties.Resources.ico_delete_16x.ToBitmap(), new EventHandler(context_Delete));
			this.ContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(ContextMenuStrip_Opening);

			_svcModule = null;

			//
			// Interfaces and References
			//
			_exposedCapability = null;
			_verbSymbols = new List<VerbSymbol>();
			_references = new List<ReferenceSymbol>();

			_verbDeploy = null;

			_changeService = null;
			_isVerbRemoving = false;

			//this.IsCollapsed = false;

			this.EndUpdate();
		}

		#endregion

		#region Public Members

		#region Properties
		public override bool CanSelect
		{
			get { return true; }
		}
		public override bool CanFocused
		{
			get { return true; }
		}
		public override bool CanMove
		{
			get { return true; }
		}
		public override bool CanResize
		{
			get { return true; }
		}
		public override bool IsContainer
		{
			get { return true; }
		}
		public override bool NoClip
		{
			get { return false; }
		}

		public ExposedCapabilitySymbol ExposedCapabilitySymbol
		{
			get { return _exposedCapability; }
		}
		public List<VerbSymbol> CapabilityMethods
		{
			get { return _verbSymbols; }
		}
		public List<ReferenceSymbol> References
		{
			get { return _references; }
		}
		#endregion

		#region Override
		public override object GetDragObject(Point location, MouseButtons button)
		{
			return this;
		}
		public override void DropObject(object obj, Point location, MouseButtons button)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null ) throw new NullReferenceException("RepositoryService not available.");

			//if ( this.IsCollapsed )
			//    return;

			if ( this.IsDropAllowed(obj, location, button) ) {
				if ( button == MouseButtons.Left ) {
					if ( obj is InterfaceSymbol ) {
						//AddExposedCapabilitySymbol((InterfaceSymbol)obj);
					} else if ( obj is ReferenceSymbol ) {
						AddReferenceSymbol((ReferenceSymbol)obj);
					} else if ( obj is VerbSymbol ) {
						addNewVerbSymbol((VerbSymbol)obj);
					} else {
						bool isAdded = false;
						DesignerControl dc = null;
						if ( obj is RepositoryItemBase ) {
							if ( obj is Repository.ServiceModule ) {
								Repository.ServiceModule svcmodule = obj as Repository.ServiceModule;
								CompositeReferenceSymbol crs = new CompositeReferenceSymbol();
								crs.Location = this.PointToDesignerControlClient(location);
								crs.RepositoryItem = svcmodule;
								this.Controls.Add(crs);
								if ( this.DesignerViewControl.DesignController is DesignController ) {
									( (DesignController)this.DesignerViewControl.DesignController ).ReloadItems(crs);
								}
								isAdded = true;
							} else if ( obj is Repository.Workflow ) {
								Repository.Workflow wf = obj as Repository.Workflow;
								WorkflowReferenceSymbol wrs = repSvc.CreateDesignerControl(wf) as WorkflowReferenceSymbol;
								if ( wrs != null ) {
									wrs.Location = this.PointToDesignerControlClient(location);
									wrs.IsReference = true;
									this.Controls.Add(wrs);
									isAdded = true;
								}
							} else {
								( (RepositoryItemBase)obj ).Reload();
								dc = repSvc.CreateDesignerControl((RepositoryItemBase)obj);
							}
							if ( dc is CollapsableSymbol ) {
								( (CollapsableSymbol)dc ).IsCollapsed = true;
								( (CollapsableSymbol)dc ).UseCustomCollapseClick = true;
							}
						} else {
							dc = obj as DesignerControl;
						}
						if ( !isAdded && dc != null ) {
							dc.Location = this.PointToDesignerControlClient(location);
							this.Controls.Add(dc);
						}
					}
				} else {
					this.DesignerViewControl.AddRoute((DesignerControl)obj, this);
				}
			}
		}
		public override bool IsDropAllowed(object obj, Point location, MouseButtons button)
		{
			//if ( this.IsCollapsed )
			//    return false;

			if ( obj == this ) return false;
			if ( obj is Repository.ServiceModule &&
				( (Repository.ServiceModule)obj ).ID == ( this.RepositoryItem != null ? this.RepositoryItem.ID : 0 ) ) {
				return false;
			}
			Verb v = obj as Verb;
			if ( v != null ) return false;
			VerbSymbol vsymbol = obj as VerbSymbol;
			if ( vsymbol != null ) return false;
			if ( v != null ) {
				foreach ( var vs in _verbSymbols ) {
					if ( vs.Operation != null && vs.Operation.ExposedVerb == v ) {
						return false;
					}
				}
			} else if ( vsymbol != null && vsymbol.Operation != null && vsymbol.Operation.ExposedVerb != null ) {
				foreach ( var vs in _verbSymbols ) {
					if ( vs.Operation != null && vs.Operation.ExposedVerb == vsymbol.Operation.ExposedVerb ) {
						return false;
					}
				}
			}
			return IsDropAllowed(obj.GetType(), location, button);
		}
		public override bool IsDropAllowed(Type type, Point location, MouseButtons button)
		{
			//if ( this.IsCollapsed )
			//    return false;
			if ( ( //type == typeof(InterfaceSymbol) ||
				   type == typeof(ReferenceSymbol) ||
				   type == typeof(ServiceComponentSymbol) ||
				   type == typeof(CompositeReferenceSymbol) ||
				   type.IsSubclassOf(typeof(ServiceComponentSymbol)) ||
				   type == typeof(StandaloneReferenceSymbol) ||
				   type == typeof(Selector.SelectorSymbol) ||
				   type == typeof(ServiceModuleSymbol) ||
				   type == typeof(Generic.MappingSymbol) ||
				   type == typeof(Repository.Service) ||
				   type == typeof(Repository.ServiceModule) ||
				   type == typeof(WorkflowReferenceSymbol) ||
				   type == typeof(Repository.Workflow) ||
				   type == typeof(VerbSymbol) ) &&
				  button == MouseButtons.Left )
				return true;
			else if ( ( type == typeof(BusinessServices.BusinessServiceSymbol) ||
						type == typeof(ServiceModuleSymbol) ||
						type == typeof(InterfaceSymbol) ) && button == MouseButtons.Right )
				return true;
			else
				return false;
		}

		public override bool CreateRouteEnd(DesignerControl controlStart, out IConnector connector,
			out System.Drawing.Drawing2D.LineCap cap, out System.Drawing.Drawing2D.CustomLineCap customcap,
			out RouteDockDirection dockStart, out RouteDockDirection dockEnd,
			out bool useEndConnectorAsRouteEnd)
		{
			bool ok = base.CreateRouteEnd(controlStart, out connector, out cap, out customcap, out dockStart, out dockEnd, out useEndConnectorAsRouteEnd);

			cap = System.Drawing.Drawing2D.LineCap.Custom;
			GraphicsPath path = new GraphicsPath();
			path.AddEllipse(-2.5f, -2.5f, 5f, 5f);
			customcap = new System.Drawing.Drawing2D.CustomLineCap(path, null);

			return ok;
		}

		public override void ReadXml(System.Xml.XmlReader reader)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			System.ComponentModel.BooleanConverter bc = new System.ComponentModel.BooleanConverter();
			try {
				while ( reader.Read() ) {
					switch ( reader.Name ) {
						case "DesignerControl":
							if ( reader.NodeType == System.Xml.XmlNodeType.EndElement ) {
								return;
							}
							break;
						case "ServiceModule":
							if ( reader.MoveToAttribute("id") && reader.ReadAttributeValue() )
								this.RepositoryItem = repSvc.GetItem(ItemType.Composite, int.Parse(reader.Value), false);
							if ( reader.MoveToAttribute("isMainControl") && reader.ReadAttributeValue() )
								if ( this.DesignerViewControl != null && reader.Value == true.ToString() )
									this.DesignerViewControl.MainControl = this;
							if ( reader.MoveToAttribute("isRef") && reader.ReadAttributeValue() )
								this.IsReference = (bool)bc.ConvertFromString(reader.Value);
							break;
						case "Service":
							if ( reader.MoveToAttribute("id") && reader.ReadAttributeValue() )
								this.RepositoryItem = repSvc.GetItem(ItemType.Component, int.Parse(reader.Value), false);
							if ( reader.MoveToAttribute("isMainControl") && reader.ReadAttributeValue() )
								if ( reader.Value == true.ToString() && this.DesignerViewControl != null )
									this.DesignerViewControl.MainControl = this;
							if ( reader.MoveToAttribute("isRef") && reader.ReadAttributeValue() )
								this.IsReference = (bool)bc.ConvertFromString(reader.Value);
							break;
						case "DesignerControls":
							// read child controls
							ReadChildControls(reader);
							break;
						default:
							ReadStandardProperties(reader);
							break;
					}
				}
			} finally {
				if ( _exposedCapability != null ) {
					_exposedCapability.Remove();
					_exposedCapability = null;
				}
				if ( _verbSymbols.Count > 0 ) {
					foreach ( VerbSymbol vs in _verbSymbols ) {
						vs.Removed -= verbSymbol_Removed;
						vs.Remove();
					}
					_verbSymbols.Clear();
				}
				if ( _references.Count > 0 ) {
					foreach ( ReferenceSymbol r in _references ) {
						r.Remove();
					}
					_references.Clear();
				}
				foreach ( DesignerControl dc in this.Controls ) {
					if ( dc is ExposedCapabilitySymbol ) {
						_exposedCapability = (ExposedCapabilitySymbol)dc;
					} else if ( dc is ReferenceSymbol ) {
						_references.Add((ReferenceSymbol)dc);
					} else if ( dc is VerbSymbol ) {
						VerbSymbol vs = (VerbSymbol)dc;
						vs.Removed += verbSymbol_Removed;
						_verbSymbols.Add(vs);
					}
				}
			}
		}
		internal void ReadXmlForDroppedItem(System.Xml.XmlReader reader)
		{
			try {
				while ( reader.Read() ) {
					switch ( reader.Name ) {
						case "DesignerControl":
							if ( reader.NodeType == System.Xml.XmlNodeType.EndElement ) {
								return;
							}
							break;
						case "DesignerControls":
							// read child controls
							ReadChildControls(reader);
							break;
						default:
							ReadStandardProperties(reader);
							break;
					}
				}
			} finally {
				if ( _exposedCapability != null ) {
					_exposedCapability.Remove();
					_exposedCapability = null;
				}
				if ( _verbSymbols.Count > 0 ) {
					foreach ( VerbSymbol cms in _verbSymbols ) {
						cms.Remove();
					}
					_verbSymbols.Clear();
				}
				if ( _references.Count > 0 ) {
					foreach ( ReferenceSymbol r in _references ) {
						r.Remove();
					}
					_references.Clear();
				}
				foreach ( DesignerControl dc in this.Controls ) {
					if ( dc is ExposedCapabilitySymbol ) {
						_exposedCapability = (ExposedCapabilitySymbol)dc;
					} else if ( dc is ReferenceSymbol ) {
						_references.Add((ReferenceSymbol)dc);
					} else if ( dc is VerbSymbol ) {
						_verbSymbols.Add((VerbSymbol)dc);
					}
				}
			}
		}
		public override void WriteXml(System.Xml.XmlWriter writer)
		{
			System.ComponentModel.BooleanConverter bc = new System.ComponentModel.BooleanConverter();
			WriteStandardProperties(writer);

			if ( _svcModule != null ) {
				writer.WriteStartElement("ServiceModule");
				writer.WriteAttributeString("id", _svcModule.ID.ToString());
				writer.WriteAttributeString("name", _svcModule.Name);
				if ( this.DesignerViewControl.MainControl == this )
					writer.WriteAttributeString("isMainControl", true.ToString());
				else
					writer.WriteAttributeString("isMainControl", false.ToString());
				writer.WriteAttributeString("isRef", bc.ConvertToString(this.IsReference));
				writer.WriteEndElement();
			}

			WriteChildControls(writer);
		}

		public override void InitializeNew(IServiceProvider serviceProvider)
		{
			RepositoryService repSvc = (RepositoryService)serviceProvider.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			base.InitializeNew(serviceProvider);

			//AddExposedCapabilitySymbol(repSvc.CreateDesignerControl(ItemType.ExposedCapability, false) as ExposedCapabilitySymbol);
		}

		public override object GetService(Type serviceType)
		{
			if ( _svcModule != null )
				return _svcModule.GetService(serviceType);
			else
				return base.GetService(serviceType);
		}

		public override void Dispose()
		{
			try {
				_changeService.RepositoryChanged -= _changeService_RepositoryChanged;
				_changeService = null;
			} catch { }
			base.Dispose();
		}
		#endregion

		#region IRepositoryItemSymbol Members

		public bool SaveHierarchy
		{
			get { return false; }
		}

		public bool IsReference
		{
			get { return _isReference; }
			set { _isReference = value; }
		}

		public bool CanBeMainControl
		{
			get { return true; }
		}

		public OpenComposite.EII.Repository.IRepositoryItem RepositoryItem
		{
			get
			{
				return _svcModule;
			}
			set
			{
				if ( !( value is ServiceModule ) ) {
					throw new InvalidOperationException("RepositoryItem must be a ServiceModule.");
				}
				_svcModule = value as ServiceModule;
				if ( _svcModule != null ) {
					_svcModule.CompositeSymbol = this;
					doItemChanged();
				} else {
					_svcModule = null;
				}
			}
		}

		public void Load(int idRepository, int idDomain)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null ) {
				throw new NullReferenceException("RepositoryService not available.");
			}

			BindingListEx<Verb> verbs = _svcModule.GetVerbs();
			this.BeginUpdate();
			if ( _exposedCapability == null ) {
				ExposedCapabilitySymbol newECS = new ExposedCapabilitySymbol();
				newECS.ServiceModule = _svcModule;
				newECS.VerbsChanged += new EventHandler(exposedCapability_VerbsChanged);
				AddExposedCapabilitySymbol(newECS);
			} else {
				_exposedCapability.ServiceModule = _svcModule;
				_exposedCapability.VerbsChanged += new EventHandler(exposedCapability_VerbsChanged);
			}
			addVerbs(verbs);
			validateVerbs();
			this.EndUpdate();
		}

		public bool Save(int idRepository, int idDomain)
		{
			if ( _svcModule == null )
				return false;

			bool ok = _svcModule.Save();
			if ( ok ) {
				Capability c = _svcModule.Capability;
				if ( c != null ) {
					foreach ( Verb v in c.GetVerbs() ) {
						Global.Data.AddRepositoryHierarchy(_svcModule, v, Global.Status.CurrentRepositoryId);
					}
				}
			}
			return ok;
		}

		public bool Delete(bool bAsk)
		{
			if ( _svcModule == null )
				return true;

			return _svcModule.Delete(bAsk);
		}

		#endregion

		#endregion

		#region Protected Members

		#region Fields
		protected bool disableCollapseExpandReposition = false;
		#endregion

		#region Methods
		protected void AddExposedCapabilitySymbol(ExposedCapabilitySymbol symbol)
		{
			//if ( this.IsCollapsed )
			//    symbol.Collapse();
			//else
			symbol.Expand();

			int x = -( symbol.Width / 2 ) - 5;
			int y = ( this.ClientRectangle.Height / 2 ) - ( symbol.Height / 2 );// ( this.IsCollapsed ? 20 : 40 );

			symbol.Location = new Point(x, y);
			symbol.Removed += new EventHandler(symbol_Removed);

			if ( _exposedCapability != null ) this.Controls.Remove(_exposedCapability);
			this.Controls.Add(symbol);
			_exposedCapability = symbol;
		}

		protected void AddReferenceSymbol(ReferenceSymbol symbol)
		{
			//if ( this.IsCollapsed )
			//    symbol.Collapse();
			//else
			symbol.Expand();

			int x = this.ClientRectangle.Width - ( symbol.Width / 2 ) + 10;
			int y = 40;//( this.IsCollapsed ? 20 : 40 );
			if ( _references.Count > 0 )
				y = _references[_references.Count - 1].Bottom + 20;//( this.IsCollapsed ? 10 : 20 );

			symbol.Location = new Point(x, y);
			symbol.Anchor = AnchorStyles.Top | AnchorStyles.Right;
			symbol.Removed += new EventHandler(symbol_Removed);
			this.Controls.Add(symbol);
			_references.Add(symbol);
		}
		protected void Expand()
		{
			this.BeginUpdate();
			if ( _exposedCapability != null ) {
				_exposedCapability.Expand();
				_exposedCapability.Location = new Point(
						-(int)( _exposedCapability.Width * 0.5 ) - 5,
						(int)( this.ClientRectangle.Height * 0.5 ) - ( _exposedCapability.Height / 2 ));
			}
			for ( int i = 0; i < _references.Count; i++ ) {
				_references[i].Expand();
				_references[i].Location = new Point(this.ClientRectangle.Width - ( _references[i].Width / 2 ) + 10,
													40 + ( ( _references[i].Height + 20 ) * i ));
			}
			repositionSiblings(true);
			this.EndUpdate();
		}
		protected void Collapse()
		{
			this.BeginUpdate();
			if ( _exposedCapability != null ) {
				_exposedCapability.Visible = true;
				_exposedCapability.Collapse();
				_exposedCapability.Location = new Point(
					-( _exposedCapability.Width / 2 ) - 5,
					( this.ClientRectangle.Height / 2 ) - ( _exposedCapability.Height / 2 ));
			}
			for ( int i = 0; i < _references.Count; i++ ) {
				_references[i].Visible = true;
				_references[i].Collapse();
				_references[i].Location = new Point(this.ClientRectangle.Width - ( _references[i].Width / 2 ) + 10,
													20 + ( ( _references[i].Height + 10 ) * i ));
			}
			repositionSiblings(false);
			this.EndUpdate();
		}
		#endregion

		#region Override
		protected override void OnDesignerViewChanged(EventArgs e)
		{
			base.OnDesignerViewChanged(e);
			addDesignerVerbs();
		}
		protected override Region GetMouseOverArea()
		{
			Region region = base.GetMouseOverArea();
			if ( _exposedCapability != null ) {
				region.Union(_exposedCapability.GetPaintBounds());
			}
			foreach ( ReferenceSymbol r in _references ) {
				region.Union(r.GetPaintBounds());
			}
			return region;
		}
		protected override void OnTextChanged(EventArgs e)
		{
			if ( _svcModule != null ) {
				_svcModule.Name = this.Text;
				_svcModule.Save();
				this.Name = this.Text;
			}
			base.OnTextChanged(e);
		}
		//protected override void OnCollapsing(System.ComponentModel.CancelEventArgs e)
		//{
		//    base.OnCollapsing(e);
		//}
		//protected override void OnExpanding(System.ComponentModel.CancelEventArgs e)
		//{
		//    base.OnExpanding(e);
		//}
		//protected override void OnCollapsed(EventArgs e)
		//{
		//    base.OnCollapsed(e);
		//    Collapse();
		//}
		//protected override void OnExpanded(EventArgs e)
		//{
		//    base.OnExpanded(e);
		//    Expand();
		//}

		//protected override void OnCustomCollapseButtonClick()
		//{
		//    openDiagram();
		//}

		protected override void OnModeChanged(EventArgs e)
		{
			bool bIsITMode = ( this.Mode == RepositoryModes.ITMode && this == this.DesignerViewControl.MainControl );
			this.ContextMenuStrip.Items[0].Enabled = !bIsITMode;
		}

		protected override void OnControlAdded(DesignerControl ctrl)
		{
			//if ( this.IsCollapsed && !( ctrl is InterfaceSymbol || ctrl is ReferenceSymbol ) )
			//    ctrl.Visible = false;
		}
		protected override void OnVisibleChanged()
		{
			//this.BeginUpdate();
			//foreach ( DesignerControl dc in this.Controls ) {
			//    if ( !( this.IsCollapsed && this.Visible ) ||
			//          ( dc == this.NameTextBox || dc == this.CollapseButton ||
			//            dc is InterfaceSymbol || dc is ReferenceSymbol ) ) {
			//        dc.Visible = this.Visible;
			//        if ( dc == this.CollapseButton && !this.ShowCollapseButton )
			//            dc.Visible = false;
			//    }
			//}
			//this.EndUpdate();
		}

		//protected override void SetNameTextboxBounds(bool isCollapsed)
		//{
		//    Rectangle rclient = this.ClientRectangle;
		//    if ( isCollapsed ) {
		//        this.NameTextBox.Bounds = new Rectangle(10, 0, rclient.Width - 10 - 20, (int)( rclient.Height / 2 ));
		//        this.NameTextBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
		//    } else {
		//        this.NameTextBox.Bounds = new Rectangle(0, 0, rclient.Width - 20, 15);
		//        this.NameTextBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
		//    }
		//}

		#endregion

		#endregion

		#region Private Members

		#region Constants
		private const int cVerbSymbolXPos = 150;
		#endregion

		#region Fields
		private bool _isReference = false;
		private ServiceModule _svcModule;
		private ExposedCapabilitySymbol _exposedCapability;
		private List<VerbSymbol> _verbSymbols;
		private List<ReferenceSymbol> _references;
		private DesignerVerb _verbDeploy;
		private IRepositoryChangeService _changeService;
		private volatile bool _isVerbRemoving;
		#endregion

		#region Methods
		private void repositionSiblings(bool bExpand)
		{
			// REMOVED: RE 14.12.2007 because we don't want to expand the composite, so we don't need the reposition

			//Size szChange = this.ExpandedSize - this.CollapsedSize;
			//IEnumerator controls = null;
			//if ( this.Parent != null ) {
			//    controls = this.Parent.Controls.GetEnumerator();
			//} else if ( this.DesignerViewControl != null ) {
			//    controls = this.DesignerViewControl.DesignerControls.ControlsWithoutRoutes.GetEnumerator();
			//}
			//if ( controls != null ) {
			//    while ( controls.MoveNext() ) {
			//        DesignerControl dc = controls.Current as DesignerControl;
			//        if ( dc is CollapseButton )
			//            continue;
			//        if ( dc != null ) {
			//            if ( dc.Left > this.Left ) {
			//                if ( bExpand )
			//                    dc.Left += szChange.Width;
			//                else
			//                    dc.Left -= szChange.Width;
			//            } else if ( dc.Top > this.Top && dc.Right > this.Left ) {
			//                if ( bExpand )
			//                    dc.Top += szChange.Height;
			//                else
			//                    dc.Top -= szChange.Height;
			//            }
			//        }
			//    }
			//}
			#region old code
			//int iCurrent = 0;
			//List<DesignerControl> listMove = new List<DesignerControl>();
			//DesignerControl dcCurrent = this;
			//Size szChange = this.ExpandedSize - this.CollapsedSize;
			//while ( dcCurrent != null ) {
			//    ServiceModuleSymbol module = dcCurrent as ServiceModuleSymbol;
			//    if ( module != null ) {
			//        foreach ( ReferenceSymbol refsymbol in module._references ) {
			//            listMove.Add(refsymbol.Interface.Parent);
			//            refsymbol.Interface.Parent.Left += szChange.Width;
			//        }
			//    }
			//    if ( listMove.Count > iCurrent ) {
			//        dcCurrent = listMove[iCurrent];
			//        iCurrent++;
			//    } else {
			//        dcCurrent = null;
			//    }
			//}
			#endregion
		}

		private void doItemChanged()
		{
			if ( _svcModule != null ) {
				this.Text = _svcModule.Name;
				addDesignerVerbs();

				if ( _changeService == null ) {
					_changeService = _svcModule.GetService(typeof(IRepositoryChangeService)) as IRepositoryChangeService;
					if ( _changeService != null ) {
						_changeService.RepositoryChanged += _changeService_RepositoryChanged;
					}
				}
			}
		}

		private void addDesignerVerbs()
		{
			if ( this.DesignerViewControl != null ) {
				IController controller = this.DesignerViewControl.DesignController as IController;
				if ( controller != null ) {
					if ( _verbDeploy != null && controller.Verbs.Contains(_verbDeploy) ) {
						controller.Verbs.Remove(_verbDeploy);
					}
					_verbDeploy = new DesignerVerb("Generate Web Service...",
												   new EventHandler(this.context_Deploy));
					_verbDeploy.Properties.Add("Image", OpenComposite.Repository.Properties.Resources.PublishToWeb);
					_verbDeploy.Properties.Add("ImageTransparentColor", Color.Magenta);

					controller.Verbs.Add(_verbDeploy);
				}
			}
		}
		private void deployComposite()
		{
			#region old code
			//string path = null;
			//string errormsg = "";
			//foreach ( DesignerControl dc in this.Controls ) {
			//    if ( dc is OrchestrationComponentSymbol ) {
			//        OrchestrationComponentSymbol wfsymbol = (OrchestrationComponentSymbol)dc;
			//        if ( wfsymbol.ProcessOperation != null ) {
			//            List<Repository.Workflow> lstWF = Global.Data.GetOperationWorkflow(wfsymbol.ProcessOperation.ID);
			//            if ( lstWF != null ) {
			//                foreach ( Repository.Workflow wf in lstWF ) {
			//                    if ( string.IsNullOrEmpty(path) ) {
			//                        FolderBrowserDialog dlgSelectFolder = new FolderBrowserDialog();
			//                        dlgSelectFolder.Description = "Select a folder to deploy the orchestration.";
			//                        dlgSelectFolder.RootFolder = System.Environment.SpecialFolder.MyComputer;
			//                        if ( dlgSelectFolder.ShowDialog() != DialogResult.OK )
			//                            return;
			//                        path = dlgSelectFolder.SelectedPath;
			//                    }
			//                    try {
			//                        Deployment.DeployWorkflow(path, wf, false);
			//                    } catch ( Exception ex ) {
			//                        errormsg += string.Format("{0}{1}", ex.Message, Environment.NewLine);
			//                    }
			//                }
			//            }
			//        }		
			//    }
			//}
			//if ( !string.IsNullOrEmpty(errormsg) ) {
			//    MessageBox.Show(errormsg, "Deploy " + this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
			//} else {
			//    MessageBox.Show("Composite Successfully Deployed.", "Deploy " + this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
			//}
			#endregion
			DesignController ctrl = this.DesignerViewControl.DesignController as DesignController;
			Forms.FormDeployServiceModule frm = new Forms.FormDeployServiceModule(_svcModule);
			if ( ctrl != null ) {
				WeifenLuo.WinFormsUI.Docking.DockPanel dp = ctrl.DesignerDockContent.DockPanel;
				Rectangle rectFloat = new Rectangle(
					new Point(dp.Left + dp.Width / 2 - frm.Width / 2, dp.Top + dp.Height / 2 - frm.Height / 2), frm.Size);
				rectFloat = dp.RectangleToScreen(rectFloat);
				frm.Show(dp, rectFloat);
			} else {
				frm.Show();
			}
		}
		private void openDiagram()
		{
			DesignController dc = this.DesignerViewControl.DesignController as DesignController;
			if ( dc != null ) {
				dc.OpenDiagram(this.RepositoryItem);
			}
		}

		private void validateVerbs()
		{
			List<VerbSymbol> verbsymbols = getCurrentVerbSymbols();
			foreach ( var vs in verbsymbols.ToArray() ) {
				if ( vs.Operation == null || vs.Operation.ExposedVerb == null ) {
					vs.Remove();
				}
			}
		}
		private List<VerbSymbol> getCurrentVerbSymbols()
		{
			List<VerbSymbol> verbsymbols = new List<VerbSymbol>();
			foreach ( DesignerControl dc in this.Controls ) {
				VerbSymbol vs = dc as VerbSymbol;
				if ( vs != null ) {
					verbsymbols.Add(vs);
				}
			}
			return verbsymbols;
		}
		private void addVerbs(IList<Verb> verbs)
		{
			if ( verbs == null ) return;
			int maxy = 0;
			foreach ( Verb verb in verbs ) {
				int y = addVerb(verb);
				if ( y > maxy ) maxy = y;
			}
			foreach ( VerbSymbol vs in _verbSymbols.ToArray() ) {
				if ( vs.Operation == null || vs.Operation.ExposedVerb == null ||
					 !verbs.Contains(vs.Operation.ExposedVerb) ) {
					vs.Remove();
					removeVerbSymbol(vs);
				}
			}
			if ( maxy > 0 ) {
				if ( ( maxy + 50 ) > 300 ) {
					this.Height = maxy + 50;
					this.MinimumSize = new Size(this.MinimumSize.Width, this.Height);
				}
			}
		}
		private int addVerb(Verb verb)
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			Debug.Assert(repSvc != null, "RepositoryService not available.");

			bool exists = false;
			int maxy = 0;
			foreach ( VerbSymbol vs in _verbSymbols ) {
				if ( vs.Operation != null && vs.Operation.ExposedVerb == verb ) {
					exists = true;
					if ( !_svcModule.ExtendedProperties.ExposedVerbOperation.ContainsKey(verb.ID) ) {
						_svcModule.ExtendedProperties.ExposedVerbOperation.Add(verb.ID, vs.Operation.ID);
					}
					break;
				}
				if ( vs.Bottom > maxy ) maxy = vs.Bottom;
			}
			if ( !exists ) {
				IRepositoryItem parentItem = null;
				Operation newOp = repSvc.GetNewItem<Operation>(false, ref parentItem);
				Debug.Assert(newOp != null);
				newOp.BeginEdit();
				newOp.Name = verb.Name;
				newOp.Description = verb.Description;
				newOp.ExposedVerb = verb;
				newOp.EndEdit(true);
				VerbSymbol vs = repSvc.CreateDesignerControl(newOp) as VerbSymbol;
				vs.Location = new Point(cVerbSymbolXPos, maxy + 50);
				vs.Removed += verbSymbol_Removed;
				_verbSymbols.Add(vs);
				this.Controls.Add(vs);
				if ( this.DesignerViewControl != null ) {
					this.DesignerViewControl.AddRoute(_exposedCapability, vs);
				}
				if ( _svcModule.ExtendedProperties.ExposedVerbOperation.ContainsKey(verb.ID) ) {
					_svcModule.ExtendedProperties.ExposedVerbOperation.Remove(verb.ID);
				}
				_svcModule.ExtendedProperties.ExposedVerbOperation.Add(verb.ID, newOp.ID);
				maxy += vs.Height + 50;
			} else {
				maxy = -1;
			}
			return maxy;
		}

		private void addNewVerbSymbol(VerbSymbol verbSymbol)
		{
			int maxy = 0;
			foreach ( VerbSymbol cms in _verbSymbols ) {
				if ( cms.Bottom > maxy ) maxy = cms.Bottom;
			}
			verbSymbol.Location = new Point(cVerbSymbolXPos, maxy + 50);
			verbSymbol.Removed += new EventHandler(verbSymbol_Removed);
			_verbSymbols.Add(verbSymbol);
			this.Controls.Add(verbSymbol);
			this.DesignerViewControl.AddRoute(_exposedCapability, verbSymbol);
			Verb verb = verbSymbol.Operation.ExposedVerb;
			if ( verb != null ) {
				Global.Data.AddRepositoryHierarchy(_svcModule, verb, Global.Status.CurrentRepositoryId);
				if ( _svcModule.ExtendedProperties.ExposedVerbOperation.ContainsKey(verb.ID) ) {
					_svcModule.ExtendedProperties.ExposedVerbOperation.Remove(verb.ID);
				}
				_svcModule.ExtendedProperties.ExposedVerbOperation.Add(verb.ID, verbSymbol.Operation.ID);
			}
			maxy = verbSymbol.Bottom;
			if ( ( maxy + 50 ) > 300 ) {
				this.Height = maxy + 50;
				this.MinimumSize = new Size(this.MinimumSize.Width, this.Height);
			}
		}

		private void removeVerbSymbol(VerbSymbol verbSymbol)
		{
			if ( verbSymbol == null ) return;

			_isVerbRemoving = true;
			try {
				if ( verbSymbol.Operation != null ) {
					Verb v = verbSymbol.Operation.ExposedVerb;
					if ( v != null ) {
						Global.Data.DeleteRepositoryHierarchy(this._svcModule, v);
					}
					Global.Data.DeleteRepositoryItem(ItemType.Operation, verbSymbol.Operation.ID);
				}
				if ( _verbSymbols.Contains(verbSymbol) ) {
					_verbSymbols.Remove(verbSymbol);
					repositionVerbSymbols();
				}
			} finally {
				_isVerbRemoving = false;
			}
		}

		private void repositionVerbSymbols()
		{
			int maxy = 0;
			foreach ( VerbSymbol vs in _verbSymbols ) {
				maxy += 50;
				vs.Location = new Point(cVerbSymbolXPos, maxy);
				maxy += vs.Height;
			}
			autoSizeComposite();
		}
		private void autoSizeComposite()
		{
			int width = 0;
			int height = 0;
			foreach ( DesignerControl dc in this.Controls ) {
				if ( !( dc is ExposedCapabilitySymbol && dc is OpenComposite.Base.Designer.TextBox ) ) {
					if ( dc.Right > width ) width = dc.Right + 50;
					if ( dc.Bottom > height ) height = dc.Bottom + 50;
				}
			}
			if ( ( width + 20 ) < 600 ) width = 600;
			if ( ( height + 20 ) < 300 ) height = 300;
			this.MinimumSize = new Size(width, height);
			this.Size = new Size(width, height);
		}
		#endregion

		#region Event Handlers
		private void ContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
		{
			e.Cancel = true;
			return;

			//bool showOpen = true;
			//bool showRemoveDelete = true;
			//if ( this.IsCollapsed ) {
			//    this.ContextMenuStrip.Items["opencomposite"].Text = "Open Service";
			//} else {
			//    this.ContextMenuStrip.Items["opencomposite"].Text = "Collapse Service";
			//}
			#region Old Code
			//bool showDeploy = false;
			//if ( !this.ShowCollapseButton ) {
			//    showOpen = true;
			//}
			//foreach ( DesignerControl dc in this.Controls ) {
			//    if ( dc is OrchestrationComponentSymbol ) {
			//        showDeploy = true;
			//        break;
			//    }
			//}
			//this.ContextMenuStrip.Items[2].Visible = showDeploy;
			//this.ContextMenuStrip.Items[3].Visible = showDeploy;
			#endregion

			//this.ContextMenuStrip.Items[0].Visible = showOpen;
			//this.ContextMenuStrip.Items[1].Visible = showOpen;

			//showRemoveDelete = !( this.DesignerViewControl.MainControl == this );

			//this.ContextMenuStrip.Items[3].Visible = showRemoveDelete;
			//this.ContextMenuStrip.Items[4].Visible = showRemoveDelete;
			//this.ContextMenuStrip.Items[5].Visible = showRemoveDelete;
		}

		private void context_Remove(object sender, EventArgs e)
		{
			this.Remove();
		}
		private void context_Delete(object sender, EventArgs e)
		{
			if ( this.Delete(true) )
				this.Remove();
		}
		private void context_Deploy(object sender, EventArgs e)
		{
			deployComposite();
		}
		private void context_Open(object sender, EventArgs e)
		{
			//if ( this.UseCustomCollapseClick )
			//    openDiagram();
			//else {
			//    this.IsCollapsed = !this.IsCollapsed;
			//}
		}
		private void symbol_Removed(object sender, EventArgs e)
		{
			if ( sender is ReferenceSymbol )
				_references.Remove((ReferenceSymbol)sender);
			else if ( sender is ExposedCapabilitySymbol )
				_exposedCapability = null;
		}

		private void exposedCapability_VerbsChanged(object sender, EventArgs e)
		{
			//this.BeginUpdate();
			addVerbs(_svcModule.GetVerbs());
			//this.EndUpdate();
		}

		private void verbSymbol_Removed(object sender, EventArgs e)
		{
			removeVerbSymbol(sender as VerbSymbol);
		}

		private void _changeService_RepositoryChanged(object sender, RepositoryChangedEventArgs e)
		{
			string newValue = e.NewValue == null ? "" : e.NewValue.ToString();
			if ( e.RepositoryItem == _svcModule && newValue == "Parent" && !_isVerbRemoving ) {
				addVerbs(_svcModule.GetVerbs());
			}
		}

		#endregion

		#endregion
	}
}
